#ifndef SERVER_ENDPOINT_H
#define SERVER_ENDPOINT_H

#include <memory>
#include <unordered_map>
#include <pistache/http.h>
#include <pistache/router.h>
#include <pistache/endpoint.h>
#include "ElasticsearchClient/ElasticsearchClient.h"
#include "HBaseClient/HBaseClient.h"
#include "HdfsClient/HdfsClient.h"
#include "util.h"

typedef void(*HandleFunc)(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);

class ServerEndpoint
{
public:
    ServerEndpoint(const Pistache::IP &ip, const Pistache::Port &port, size_t thr);
    ~ServerEndpoint();
    void Start();
    void AsyncStart();
    void Stop();
    void AddAnalyzeHandle(const std::string& name, const std::string& desc, HandleFunc func);

private:
    void SetupRoutes();

private:
    Pistache::Address address;
    Pistache::Rest::Router router;
    std::shared_ptr<Pistache::Http::Endpoint> httpEndpoint;
    std::shared_ptr<ElasticsearchClient> elasticSearchClient;
    std::shared_ptr<HBaseClient> hbaseClient;
    std::shared_ptr<HdfsClient> hdfsClient;

private:    //Handles
    void DefaultHandle(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);

    void SayHello(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);


    void ManageStatus(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);

    void ManagePut(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);
    void ManageGet(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);
    void ManageDel(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);

    void FilePut(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);
    void FileGet(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);
    void FileDel(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);

    void AnalyzeManage(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);

    void Search(const Pistache::Rest::Request& request, Pistache::Http::ResponseWriter response);

    std::unordered_map<std::string, std::tuple<std::string, HandleFunc>> handles;
};


#endif //SERVER_ENDPOINT_H
